home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
BBS Toolkit
/
BBS Toolkit.iso
/
remote
/
u_orig.zip
/
U-ORIG.C
next >
Wrap
C/C++ Source or Header
|
1992-07-09
|
25KB
|
716 lines
/* **********************************************************************
* U-Orig.C User specific origin lines. *
* *
* For RemoteAccess. *
* *
* Written by Fredric L. Rice, 1992, The Skeptic Tank, 1:102/890.0. *
* *
* This program will scan the DOREINFO1.DEF file which looks a bit *
* like this: *
* *
* THE SKEPTIC TANK *
* FREDRIC *
* RICE *
* COM0 *
* 0 BAUD,N,8,1 *
* 0 *
* FREDRIC *
* RICE *
* GLENDORA, CA *
* 1 *
* 6000 *
* 287 *
* *
* The name of the user is extracted and it is compared against an *
* entry in the U-ORIG.DAT file to see if this user has created a new *
* origin line for himself or herself. If the name is found, the text *
* for the origin line is selected, else the default origin line *
* which is found in the U-ORIG.CFG file is used. *
* *
* The origin information is inserted into the MESSAGES.RA file which *
* contains the name of the conference (The title) along with the *
* origin line to use. This is acceptable for people who don't want *
* to change the default origin line as the SysOp will define one for *
* them. *
* *
********************************************************************** */
#include <bios.h>
#include <ctype.h>
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
/* **********************************************************************
* How about any macros. *
* *
********************************************************************** */
#define skipspace(s) while(isspace(*s)) ++(s)
#define TRUE 1
#define FALSE 0
#define BOOL unsigned char
/* **********************************************************************
* Define macros that the System Operator may wish to change. *
* *
********************************************************************** */
#define Input_Time_Out 30 /* 30 second keyboard time-out */
/* **********************************************************************
* Define some global data. *
* *
********************************************************************** */
static char default_origin[201];
static char origin_to_use[201];
static char full_path[201];
static char user_name[201];
static time_t t_start, t_end;
static int com_assignment;
static int user_count = 0;
static BOOL local_mode;
static long security_value = 0L;
static long allowed_security = 0L;
/* **********************************************************************
* Here is the data structure for the MESSAGES.RA file that we know *
* about. Some of the informations format is not known yet we will *
* simply bypass it all. *
* *
********************************************************************** */
static struct Messages_RA {
char title_length; /* 1 byte length of next field. */
char title[40]; /* Title of the folder */
char unknown[25]; /* Unkown so we'll simply skip them */
char origin_length; /* 1 byte length of next field */
char origin[61]; /* Origin line of the folder */
} MRA; /* Make one called 'MRA.' */
/* **********************************************************************
* Return TRUE if there is a byte waiting, else return FALSE. *
* *
********************************************************************** */
static BOOL have_byte(void)
{
int result;
if (kbhit() != 0) return(TRUE);
if (! local_mode) {
result = bioscom(3, 0, com_assignment);
return((result & 0x0100) != 0);
}
return(FALSE);
}
/* **********************************************************************
* Get the byte. *
* *
********************************************************************** */
static unsigned char get_byte(void)
{
int result;
if (kbhit() != 0)
return(getch());
if (! local_mode) {
result = bioscom(2, 0, com_assignment);
return(result & 0xFF);
}
return(0);
}
/* **********************************************************************
* Simply send a byte. *
* *
********************************************************************** */
static void send_byte(unsigned char byte)
{
if (!local_mode) {
if (byte != 0x0d) {
if (byte == 0x0a) {
(void)bioscom(1, 0x0d, com_assignment);
if (have_byte()) {
(void)get_byte();
}
}
(void)bioscom(1, byte, com_assignment);
}
}
(void)putchar(byte);
if (! local_mode) {
if (have_byte()) {
(void)get_byte();
}
}
}
/* **********************************************************************
* Send the string. *
* *
********************************************************************** */
static void print_buffer(char *message)
{
while (*message)
send_byte(*message++);
}
/* **********************************************************************
* Get some input. *
* *
* This function is a very simple input function which supplies only *
* a few features. *
* *
* Backspace is checked for and will erase the input data stream if *
* any remains. *
* *
* It performs bounds checking to see if the input length would *
* exceed the length of the buffer. *
* *
* It employs the inactivity time-out timers. *
* *
********************************************************************** */
static void input(char *to_this, int how_many)
{
int b_count;
char byte, report[10];
time_t t_start, t_end;
b_count = 0;
(void)time(&t_start);
(void)time(&t_end);
/*
An endless loop will help. A time-out is employed to make sure
that we exit the program if no keys are typed after a long time
only if the program is being run on a COM port.
*/
while (TRUE) {
(void)time(&t_end);
if (difftime(t_end, t_start) > Input_Time_Out) {
print_buffer("\n!!! Keyboard Timed out !!!\n");
(void)fcloseall();
exit(11);
}
if (have_byte()) {
byte = get_byte();
if (byte > 0) {
if (byte == 0x08) { /* Backspace? */
if (b_count > 0) {
to_this[b_count--] = (char)NULL;
(void)sprintf(report, "%c %c", 0x08, 0x08);
print_buffer(report);
}
}
else if (byte == 0x0d) { /* Carriage return? */
putchar(0x0d);
putchar(0x0a);
(void)send_byte(0x0d);
(void)send_byte(0x0a);
return;
}
else {
if ((b_count + 1) == how_many) {
send_byte(0x07);
}
else {
to_this[b_count++] = byte;
to_this[b_count] = (char)NULL;
(void)send_byte(byte); /* Echo to port */
}
}
}
}
}
}
/* **********************************************************************
* Get the configuration out of the U-ORIG.CFG file. *
* *
********************************************************************** */
static void extract_configuration(void)
{
FILE *config;
char record[201], *point;
if ((config = fopen("U-ORIG.CFG", "rt")) == (FILE *)NULL) {
(void)printf("Unable to locate config file: U-ORIG.CFG!\n");
fcloseall();
exit(10);
}
(void)strcpy(default_origin, ".");
(void)strcpy(full_path, ".");
while (! feof(config)) {
(void)fgets(record, 200, config);
if (! feof(config)) {
point = record;
skipspace(point);
if (! strnicmp(point, "default", 7)) {
point += 7;
skipspace(point);
point[strlen(point) - 1] = (char)NULL;
(void)strcpy(default_origin, point);
}
else if (! strnicmp(point, "path", 4)) {
point += 4;
skipspace(point);
point[strlen(point) - 1] = (char)NULL;
(void)strcpy(full_path, point);
if (full_path[strlen(full_path) - 1] != '\\') {
(void)strcat(full_path, "\\");
}
}
else if (! strnicmp(point, "security", 8)) {
point += 8;
skipspace(point);
allowed_security = atol(point);
}
}
}
(void)fclose(config);
if (default_origin[0] == '.' && default_origin[1] == (char)NULL) {
(void)printf("Config file is missing 'default' statement!\n");
fcloseall();
exit(10);
}
if (full_path[0] == '.' && full_path[1] == (char)NULL) {
(void)printf("Config file is missing 'path' statement!\n");
fcloseall();
exit(10);
}
if (allowed_security == 0L) {
(void)printf("Config file is missing 'security' statement!\n");
fcloseall();
exit(10);
}
}
/* **********************************************************************
* Get the users name out of the door file. *
* *
********************************************************************** */
static void extract_door_file(void)
{
FILE *door;
char record[201], *point;
char file_name[201];
unsigned char loop;
(void)sprintf(file_name, "%s%s", full_path, "DORINFO1.DEF");
if ((door = fopen(file_name, "rt")) == (FILE *)NULL) {
(void)printf("Unable to locate door file: %s!\n", file_name);
fcloseall();
exit(10);
}
for (loop = 0; loop < 3; loop++)
(void)fgets(record, 200, door);
/*
* Get the COM port assignment
*/
(void)fgets(record, 200, door); /* COMn assignment */
if (! feof(door)) {
point = record;
skipspace(point);
point += 3;
com_assignment = atoi(point);
if (*point != '0') com_assignment--;
}
else {
(void)printf("DORINFO1.DEF file is missing COM port assignment!\n");
fcloseall();
exit(10);
}
if (com_assignment > 8 || com_assignment < 0) {
(void)printf("DORINFO1.DEF file has strange COM port assignment!\n");
fcloseall();
exit(10);
}
(void)fgets(record, 200, door); /* Baud rate */
(void)fgets(record, 200, door); /* Unknown */
/*
* Read the first name
*/
(void)fgets(record, 200, door); /* Get first name */
if (! feof(door)) {
point = record;
skipspace(point);
point[strlen(point) - 1] = (char)NULL;
(void)strcpy(user_name, point);
(void)strcat(user_name, " ");
}
else {
(void)printf("DORINFO1.DEF file is missing first name!\n");
fcloseall();
exit(10);
}
(void)fgets(record, 200, door); /* Get second name */
if (! feof(door)) {
point = record;
skipspace(point);
point[strlen(point) - 1] = (char)NULL;
(void)strcat(user_name, point);
}
else {
(void)printf("DORINFO1.DEF file is missing first name!\n");
fcloseall();
exit(10);
}
(void)fgets(record, 200, door); /* City and state */
(void)fgets(record, 200, door); /* Another line to ignore */
(void)fgets(record, 200, door); /* Security */
security_value = atol(record);
(void)fclose(door);
(void)printf("User: '%s'\n", user_name);
}
/* **********************************************************************
* Scan the U-ORIG file name for a match if there is one. If there *
* is, copy the users origin line to the 'origin_to_use' array and *
* then return. If there is not, copy the default_origin to the *
* 'origin_to_use' array and then return. *
* *
********************************************************************** */
static BOOL match_user_name(void)
{
FILE *data_file;
char file_name[201];
char record[201], *point;
int search_length;
(void)sprintf(file_name, "%s%s", full_path, "U-ORIG.DAT");
if ((data_file = fopen(file_name, "rt")) == (FILE *)NULL) {
(void)strcpy(origin_to_use, default_origin);
(void)printf("Origin: DEFAULT\n");
return(FALSE);
}
search_length = strlen(user_name);
while (! feof(data_file)) {
(void)fgets(record, 200, data_file);
if (! feof(data_file)) {
point = record;
skipspace(point);
if (! strnicmp(point, user_name, search_length)) {
point += search_length;
skipspace(point);
point[strlen(point) - 1] = (char)NULL;
(void)strcpy(origin_to_use, point);
(void)fclose(data_file);
(void)printf("Origin: %d '%s'\n", user_count, origin_to_use);
return(TRUE);
}
user_count++;
}
}
(void)fclose(data_file);
(void)strcpy(origin_to_use, default_origin);
(void)printf("Origin: DEFAULT\n");
return(FALSE);
}
/* **********************************************************************
* Apply the origin line to all alive folders. *
* *
********************************************************************** */
static void apply_origin_line(void)
{
unsigned int loop;
FILE *ra_file;
char file_name[201];
unsigned char origin_length;
int folder_count, result;
char report[101];
(void)sprintf(file_name, "%s%s", full_path, "MESSAGES.RA");
if ((ra_file = fopen(file_name, "r+b")) == (FILE *)NULL) {
(void)printf("Couldn't find file: %s!\n", file_name);
fcloseall();
exit(10);
}
origin_length = strlen(origin_to_use);
folder_count = 0;
print_buffer("\nSetting origins...\n");
for (loop = 0; loop < 200; loop++) {
fseek(ra_file, (long)sizeof(struct Messages_RA) * loop, SEEK_SET);
result = fread(&MRA, sizeof(struct Messages_RA), 1, ra_file);
if (result != 1) {
(void)printf("Couldn't read record %d from file %s! Result %d\n",
loop, file_name, result);
fcloseall();
exit(10);
}
if (0 != MRA.title_length) {
MRA.origin_length = origin_length;
(void)strncpy(MRA.origin, origin_to_use, origin_length);
fseek(ra_file, (long)sizeof(struct Messages_RA) * loop, SEEK_SET);
result = fwrite(&MRA, sizeof(struct Messages_RA), 1, ra_file);
if (result != 1) {
(void)printf("Couldn't write record %d from file %s! Result: \n",
loop, file_name, result);
fcloseall();
exit(10);
}
folder_count++;
}
}
(void)fclose(ra_file);
(void)sprintf(report,
"Origin line changed in %d folders\n",
folder_count);
print_buffer(report);
}
/* **********************************************************************
* Update the user data file with the new origin line. *
* *
********************************************************************** */
static void update_user_data_file(char *new_origin_line)
{
FILE *data_file, *temp_file;
char file_name[201];
char record[201];
int loop;
(void)sprintf(file_name, "%s%s", full_path, "U-ORIG.DAT");
if ((data_file = fopen(file_name, "rt")) == (FILE *)NULL) {
if ((data_file = fopen(file_name, "wt")) == (FILE *)NULL) {
(void)printf("I can't create file: %s!\n", file_name);
fcloseall();
exit(10);
}
(void)fputs(new_origin_line, data_file);
(void)fclose(data_file);
return;
}
if ((temp_file = fopen("U-ORIG.TMP", "wt")) == (FILE *)NULL) {
(void)printf("I can't create work file: U-ORIG.TMP!\n");
fcloseall();
exit(11);
}
/*
* Read up to the users record, dumping it into the temp file.
*/
for (loop = 0; loop < user_count; loop++) {
(void)fgets(record, 200, data_file);
if (! feof(data_file)) {
(void)fputs(record, temp_file);
}
}
/*
* Write new record to temp file, read old record from original file
*/
(void)fputs(user_name, temp_file);
(void)fputs(" ", temp_file);
(void)fputs(new_origin_line, temp_file);
(void)fputs("\n", temp_file);
(void)fgets(record, 200, data_file);
/*
* Finish reading original file, dumping to temp file.
*/
while (! feof(data_file)) {
(void)fgets(record, 200, data_file);
if (! feof(data_file)) {
(void)fputs(record, temp_file);
}
}
(void)fclose(data_file);
(void)fclose(temp_file);
unlink(file_name);
rename("U-ORIG.TMP", file_name);
}
/* **********************************************************************
* Allow the origin line to be added to the file if it's not found *
* else if it was found, display it and ask if it should be changed. *
* If it should be, ask for the new one. Then display the new one and *
* ask if it's acceptable. If it is, update the data file and then *
* apply the new update to the folders. *
* *
********************************************************************** */
static void allow_change_addition_of_origin(BOOL found)
{
char input_buffer[101];
char new_origin_line[101];
if (! found) {
another_ask_again:
print_buffer("\n\nYou have no origin line.\n\n");
print_buffer("Would you like to create one? ");
input(input_buffer, 10);
if (toupper(input_buffer[0]) == 'N') return;
if (toupper(input_buffer[0]) != 'Y') goto another_ask_again;
}
else {
ask_this_again:
print_buffer("\n\nYour origin line is:\n '");
print_buffer(origin_to_use);
print_buffer("'\n\nWould you like to change it? ");
input(input_buffer, 10);
if (toupper(input_buffer[0]) == 'N') return;
if (toupper(input_buffer[0]) != 'Y') goto ask_this_again;
}
try_it_again:
print_buffer("\n\nEnter new origin line:\n");
print_buffer("Must be from 10 to 60 characters in length:\n :");
input(new_origin_line, 60);
if (strlen(new_origin_line) < 10) return;
ask_it_again:
print_buffer("\n\nI have '");
print_buffer(new_origin_line);
print_buffer("'\n");
print_buffer("\n\nShould I (K)eep, (T)ry again, (Q)uit: ");
input(input_buffer, 10);
if (toupper(input_buffer[0]) == 'Q') return;
if (toupper(input_buffer[0]) == 'T') goto try_it_again;
if (toupper(input_buffer[0]) != 'K') goto ask_it_again;
(void)strcpy(origin_to_use, new_origin_line);
update_user_data_file(new_origin_line);
}
/* **********************************************************************
* Here is the main entry point. *
* *
********************************************************************** */
void main(int argc, char *argv[])
{
char option[201];
BOOL found;
clrscr();
extract_configuration();
extract_door_file();
local_mode = FALSE;
found = match_user_name();
if (argc > 1)
(void)strcpy(option, argv[1]);
else
option[0] = (char)NULL;
if (! strnicmp(option, "update", 6)) {
print_buffer("\n\nUser-Origin Version 1.0. \n");
if (security_value >= allowed_security) {
allow_change_addition_of_origin(found);
apply_origin_line();
}
else {
print_buffer("Your security level doesn't allow updates ");
print_buffer("to your origin line.\n");
delay(200);
}
fcloseall();
exit(0);
}
else if (! strnicmp(option, "apply", 5)) {
apply_origin_line();
fcloseall();
exit(0);
}
else {
(void)strcpy(origin_to_use, default_origin);
apply_origin_line();
fcloseall();
exit(0);
}
}